import asyncio
import os
import signal
import sys

import ujson

sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))


class OrderHandler:
    def __init__(self, mgw, redis, logger):
        self.mgw = mgw
        self.redis = redis
        self.logger = logger

    async def handle_unpay_order(self, data):
        from service.order_sercice import OrderService
        order_id = data["order_id"]
        oss = OrderService(self.mgw, self.redis)
        return await oss.handle_unpay_order(order_id)


class OrderConsumerTaskProcess:

    def __init__(self):
        self.stopped = False

    async def init_process(self):
        from common.g.g import (init_db, init_redis, init_logger, init_rabbitmq_client_pool,
                                init_settings, init_id_worker)

        def stop(sig, frame):
            print(f"s收到信号：{sig}")
            self.stopped = True
        signal.signal(signal.SIGPIPE, signal.SIG_IGN)
        signal.signal(signal.SIGINT, stop)
        signal.signal(signal.SIGQUIT, stop)
        signal.signal(signal.SIGTERM, stop)
        signal.signal(signal.SIGHUP, signal.SIG_IGN)
        self.loop = asyncio.get_running_loop()
        self.settings = init_settings()
        self.mgw = init_db(self.loop)
        self.redis = init_redis()
        self.logger = init_logger()
        self.id_worker = await init_id_worker(self.settings)
        self.mq_cli = await init_rabbitmq_client_pool(self.loop, self.settings.rabbitmq_config)
        self.order_handler = OrderHandler(self.mgw, self.redis, self.logger)

    async def run(self):
        await self.init_process()
        while not self.stopped:
            async with self.mq_cli.acquire() as chan:
                queue = await chan.get_queue("unpay_order")
                msg = await queue.get(fail=False, timeout=1)
                if msg:
                    try:
                        data = ujson.loads(msg.body.decode("utf-8"))
                        self.logger.info(f"收到消息：{data}")
                        if data:
                            res = await self.order_handler.handle_unpay_order(data)
                            self.logger.info(f"处理未支付订单:{data}的结果是:{res}")
                        await msg.ack()
                    except Exception as e:
                        await asyncio.sleep(0.001)
                        self.logger.exception(f"消费消息异常:{e}, \n{msg.body}")
                await asyncio.sleep(1)
        await self.release_process()

    async def release_process(self):
        from common.g.g import close_db, close_redis, close_rabbitmq_client_pool, clear_id_worker_status
        await close_db()
        await close_redis()
        await close_rabbitmq_client_pool()
        await clear_id_worker_status()


if __name__ == '__main__':
    oct = OrderConsumerTaskProcess()
    try:
        asyncio.run(oct.run())
    except KeyboardInterrupt:
        pass
    except Exception as e:
        print(e.__class__.__name__, e)
